package com.gitee.wsl.android.ext

import android.content.Context
import android.graphics.Typeface
import android.os.Environment
import androidx.core.content.ContextCompat
import com.gitee.wsl.android.ext.FontExt.FONT_FILENAME_FILTER
import timber.log.Timber
import java.io.File
import java.io.FilenameFilter
import java.util.*

object FontExt{
    val FONT_FILENAME_FILTER = FilenameFilter { _: File?, s: String ->
        s.lowercase(Locale.getDefault()).endsWith(".ttf") || s.lowercase(Locale.getDefault()).endsWith(".otf")
    }

    val defaultFontNames = arrayOf(
        "Roboto Regular", "Roboto Light", "Roboto Bold", "Roboto Medium",
        "Monospace", "Noto Serif", "Cutive Mono", "Roboto Condensed", "Roboto Thin",
        "Roboto Black", "Coming Soon", "Carrois Gothic", "Dancing Script"
    )

    val defaultFontValues = arrayOf(
        "sans-serif-regular", "sans-serif-light", "sans-serif-bold", "sans-serif-medium",
        "monospace", "serif", "serif-monospace", "sans-serif-condensed", "sans-serif-thin",
        "sans-serif-black", "casual", "sans-serif-smallcaps", "cursive"
    )
}


fun Context.typeface(familyOrFilepath: String, typefaceStyle: Int=Typeface.NORMAL): Typeface {
    return if (!familyOrFilepath.startsWith("/")) {
        Typeface.create(familyOrFilepath, typefaceStyle)
    } else {
        try {
            if (familyOrFilepath.startsWith(com.gitee.wsl.android.ext.store.assetDirPath)) {
                Typeface.createFromAsset(
                    assets,
                    familyOrFilepath.substring(com.gitee.wsl.android.ext.store.assetDirPath.length)
                )
            } else {
                Typeface.createFromFile(familyOrFilepath)
            }
        } catch (exception: RuntimeException) {
            Timber.e("create typeface:$familyOrFilepath error:${exception}")
            typeface("sans-serif-regular", typefaceStyle)
        }
    }
}

fun Context.getAdditionalFonts(vararg additionalCheckedFolder:File): List<File>{
    val additionalFonts = ArrayList<File>()

    // Bundled fonts
    try {
        for (filename in assets.list("fonts")!!) {
            additionalFonts.add(File(com.gitee.wsl.android.ext.store.assetDirPath + "fonts", filename))
        }
    } catch (ignored: Exception) {
        Timber.e(ignored)
    }

    // Directories that are additionally checked out for fonts
    val checkedDirs: MutableList<File> = ArrayList(
        listOf(
            File(filesDir, ".app/fonts"),
            File(filesDir, ".app/Fonts"),
            File(Environment.getExternalStorageDirectory(), "fonts"),
            File(Environment.getExternalStorageDirectory(), "Fonts")
        )
    )

    additionalCheckedFolder.forEach {
        checkedDirs.add(it)
    }

    // Also check external storage directories, at the respective root and data directory
    for (externalFileDir in ContextCompat.getExternalFilesDirs(this, null)) {
        if (externalFileDir == null) {
            continue
        }
        checkedDirs.add(
            File(
                externalFileDir.absolutePath.replaceFirst(
                    "/Android/data/.*$".toRegex(),
                    "/fonts"
                )
            )
        )
        checkedDirs.add(
            File(
                externalFileDir.absolutePath.replaceFirst(
                    "/Android/data/.*$".toRegex(),
                    "/Fonts"
                )
            )
        )
        checkedDirs.add(File(externalFileDir.absolutePath, "/fonts"))
        checkedDirs.add(File(externalFileDir.absolutePath, "/Fonts"))
    }
    // Check all directories for fonts

    for (checkedDir in checkedDirs) {
        if (checkedDir.exists()) {
            checkedDir.listFiles(FONT_FILENAME_FILTER)?.forEach {
                if (!additionalFonts.contains(File(it.absolutePath.replace("/Fonts/", "/fonts/")))) {
                    additionalFonts.add(it)
                }
            }
        }
    }
    return additionalFonts
}